package acptTests;


import msgParser.Strings;

import org.junit.Before;
import org.junit.Test;

import forumSystem.User;


import reactor.Reactor;
import tokenizer.StringMessage;

	/*
	 * Correctness Test
	 * Purpose: This test will test the functionality provided by the server
	 * against all the use-cases and with varying types of input. 
	 * System will be tested on user permissions verification, error reporting,
	 * requests for non-existent objects and bad input fields in general.
	 */

public class CorrectnessTest extends ServerTest
{
	protected int testUserID;
	protected int adminID;
	protected String Policies = Strings.IMMEDIATE_NOTIFY+"\0" + Strings.FORUM_MEMBERS_NOTIFY +"\0"+ 1 +"\0" +Strings.AUTHOR_FORUM_DELETE_POST+"\0"
			  +Strings.MIN_POST_ADD_MODERATOR+"\0"+Strings.CANNOT_REMOVE_SINGLE_MODERATOR+"\0"+ 
	Strings.VALID_EMAIL_SECURITY+"\0" +Strings.REJECT_BAD_WORDS;
	
	
	@Before
	public void setUp()
	{	
		super.setUp();
		
	}
	
	public String send(String str)
	{
		return sp.processMessage(new StringMessage(str),ch).toString();
	}
	
	public void init()
	{
		send("INIT_FORUM \0 superAdminUser \0 myPass");
	}
	
	public String loginSuperAdmin()
	{
		
		send("ADMIN_LOGIN \0 superAdminUser \0 myPass");
		String username=Reactor.db.getAdminUserName();
		User admin=Reactor.db.getUserByUserName(username);
		adminID=admin.getId();
		return "";
	}
	
	public String logout()
	{
		return send("LOGOUT");
	}
	
	public String loginUser(int forumID)
	{
		String result = send("LOG_IN \0 testreg \0 pass123 \0" + forumID);
		adminID = Integer.parseInt(getWord(result.toString(), 2));
		return result;
	}
	
	public String register(int forumID)
	{
		String result = send("REGISTER \0 testreg \0 pass123 \0 max@max.com \0" + forumID);
		testUserID = Integer.parseInt(getWord(result.toString(), 1));
		return result;
	}
	
	/*
	 * PERMISSIONS
	 */
	
	@Test
	public void testGuestAddForum()
	{
		init();
		//register();
		String str = send("ADD_FORUM \0 General Discussion \0 " + testUserID +"\0" + Policies);
		assertTrue(str.startsWith("ERROR_FORUM_ADD"));
	}
	
	@Test
	public void testGuestShowAllForums()
	{
		init();
		String str = send("SHOW_FORUMS");
		assertTrue(str.startsWith("ANS_SHOW_FORUMS"));
	}
	
	@Test
	public void testNewSubForum()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 "+ adminID+ "\0" + Policies);
		logout();
		System.out.println("\n\n\n"+forum);
		assertEquals(getWord(forum, 0), "FORUM_ADDED");
		int forumID = Integer.parseInt(getWord(forum, 1));
		register(forumID);
		loginUser(forumID);
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		assertTrue(str.startsWith("ERROR_ADD_SUBFORUM"));
		logout();
		str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		assertTrue(str.startsWith("ERROR_ADD_SUBFORUM"));
	}
	
	@Test
	public void testNewMessage()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID+ "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM\0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));
		logout();
		
		String str2 = send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		assertTrue(str2.startsWith("ERROR_ADD_TOPIC"));
		register(forumID);
		loginUser(forumID);
		str2 = send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		assertTrue(str2.startsWith("TOPIC_ADDED"));
	}
	
	@Test
	public void testRegisterLoggedin()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID+ "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));
		logout();
		register(forumID);
		String str2 = send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		assertTrue(str2.startsWith("ERROR_ADD_TOPIC"));
		loginUser(forumID);
		str2 = send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		assertTrue(str2.startsWith("TOPIC_ADDED"));
	}
	
	@Test
	public void testUserAddForum()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		logout();
		register(forumID);
		loginUser(forumID);
		String str = send("ADD_FORUM \0 General Discussion \0 " + testUserID + "\0" + Policies);
		assertTrue(str.startsWith("ERROR_FORUM_ADD"));
	}
	
	@Test
	public void testUserAddSubForum()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID+ "\0"+ Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		logout();
		register(forumID);
		loginUser(forumID);
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		assertTrue(str.startsWith("ERROR_ADD_SUBFORUM"));
	}
	@Test
	public void testGuestNewReply()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID+ "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));
		logout();
		register(forumID);
		loginUser(forumID);
		String str2 = send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		int messageID = Integer.parseInt(getWord(str2, 1));
		logout();
		String str3 = send("ADD_REPLY \0 reply contents... \0" + messageID);
		assertTrue(str3.startsWith("ERROR_ADD_REPLY"));
	}
	
	@Test
	public void testShowAllUsers()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID+ "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		logout();
		register(forumID);
		loginSuperAdmin();
		String str;
		str = send("SHOW_SYSTEM_USERS");
		assertTrue(str.startsWith("ANS_SHOW_SYSTEM_USERS"));
		logout();
		loginUser(forumID);
		str = send("SHOW_SYSTEM_USERS");
		assertTrue(str.startsWith("ERROR_SHOW_SYSTEM_USERS"));
		logout();
		str = send("SHOW_SYSTEM_USERS");
		assertTrue(str.startsWith("ERROR_SHOW_SYSTEM_USERS"));
	}
	

	@Test
	public void testRemoveTopic()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));
		String str2 = send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		int topicID = Integer.parseInt(getWord(str2, 1));
		logout();
		String ans1 = send("REMOVE_TOPIC \0" + topicID);
		assertTrue(ans1.startsWith("ERROR_REMOVE_TOPIC"));
		register(forumID);
		loginUser(forumID);
		String ans2 = send("REMOVE_TOPIC \0" + topicID);
		assertTrue(ans2.startsWith("ERROR_REMOVE_TOPIC"));
	}
	
	@Test
	public void testAddSubForumModerator()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));

		logout();
		String ans3 = send("ADD_MODERATOR \0" + adminID + "\0" + subForumID); // test premissions
		assertTrue(ans3.startsWith("ERROR_ADD_MODERATOR"));
		register(forumID);
		loginUser(forumID);
		String ans4 = send("ADD_MODERATOR \0" + adminID + "\0" + subForumID);
		assertTrue(ans4.startsWith("ERROR_ADD_MODERATOR"));
	}
	
	@Test
	public void testRemoveSubForum()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));

		logout();
		String ans2 = send("REMOVE_SUBFORUM \0" + subForumID); // test premissions
		assertTrue(ans2.startsWith("ERROR_REMOVE_SUBFORUM"));
		register(forumID);
		loginUser(forumID);
		String ans3 = send("REMOVE_SUBFORUM \0" + subForumID);
		assertTrue(ans3.startsWith("ERROR_REMOVE_SUBFORUM"));
	}
	
	@Test
	public void testRemoveSubForumModerator()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));

		logout();
		String ans3 = send("REMOVE_MODERATOR \0" + adminID + "\0" + subForumID); // test premissions
		assertTrue(ans3.startsWith("ERROR_REMOVE_MODERATOR"));
		register(forumID);
		loginUser(forumID);
		String ans4 = send("REMOVE_MODERATOR \0" + adminID + "\0" + subForumID);
		assertTrue(ans4.startsWith("ERROR_REMOVE_MODERATOR"));
	}
	
	@Test
	public void testGetNumberOfMessagesInSubForum()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		
		String str1 = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str1, 1));
		send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		String str3 = send("GET_SUBFORUM_SIZE \0 " + subForumID);
		assertTrue(str3.startsWith("ANS_GET_SUBFORUM_SIZE"));
		assertEquals(getWord(str3, 1), "1");
		logout();
		str3 = send("GET_SUBFORUM_SIZE \0 " + subForumID);
		assertTrue(str3.startsWith("ANS_GET_SUBFORUM_SIZE")); // test premissions
		register(forumID);
		loginUser(forumID);
		str3 = send("GET_SUBFORUM_SIZE \0 " + subForumID);
		assertTrue(str3.startsWith("ANS_GET_SUBFORUM_SIZE"));
		
	}
	
	@Test
	public void testGetUserMSGCOUNT()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));
		str = send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		int topicID = Integer.parseInt(getWord(str, 1));

		logout();
		str = send("GET_USER_MSGCOUNT \0" + adminID); // test premissions
		assertTrue(str.startsWith("ANS_GET_USER_MSGCOUNT"));
		register(forumID);
		loginUser(forumID);
		str = send("GET_USER_MSGCOUNT \0" + testUserID);
		assertTrue(str.startsWith("ANS_GET_USER_MSGCOUNT"));
		
	}
	
	@Test
	public void testGetListOfUsersRepliedToAUser()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("ADD_SUBFORUM \0 test \0 " + forumID + "\0" + adminID);
		int subForumID = Integer.parseInt(getWord(str, 1));
		str = send("ADD_TOPIC \0 test \0 a b c d \0 " + subForumID);
		int topicID = Integer.parseInt(getWord(str, 1));
		logout();
		register(forumID);
		loginUser(forumID);
		str = send("ADD_REPLY \0 test \0" + topicID);
	
	
		logout();
		str = send("GET_AUTHORS_OF_REPLIES_TO_USER \0" + adminID); // test premissions
		assertTrue(str.startsWith("ERROR_GET_AUTHORS_OF_REPLIES_TO_USER"));
		loginUser(forumID);
		
	}
	
	@Test
	public void testGetNumberOfForums()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("GET_FORUM_COUNT"); 
		assertTrue(str.startsWith("ANS_GET_FORUM_COUNT"));
		System.out.println(str);
		assertEquals(getWord(str, 1), "1"); 				// test end case
		
		send("ADD_FORUM \0 t \0 " + adminID);
		logout();
		str = send("GET_FORUM_COUNT");
		assertTrue(str.startsWith("ANS_GET_FORUM_COUNT")); // test premissions
		register(forumID);
		loginUser(forumID);
		str = send("GET_FORUM_COUNT");
		assertTrue(str.startsWith("ANS_GET_FORUM_COUNT"));
	}
	
	@Test
	public void testGetUsernamesRegisteredToMoreThanOneForum()
	{
		init();
		loginSuperAdmin();
		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		String str = send("GET_COMMON_USERS");
		assertTrue(str.startsWith("ANS_GET_COMMON_USERS")); // test end case
		
		logout();
		str = send("GET_COMMON_USERS");
		assertTrue(str.startsWith("ERROR_GET_COMMON_USERS")); // test premissions
		register(forumID);
		loginUser(forumID);
		str = send("GET_COMMON_USERS");
		assertTrue(str.startsWith("ERROR_GET_COMMON_USERS"));
	}
	
	@Test
	public void testShowUsersOfForum()
	{
		init();
		loginSuperAdmin();

		String forum = send("ADD_FORUM \0 t \0 " + adminID + "\0" + Policies);
		int forumID = Integer.parseInt(getWord(forum, 1));
		logout();
		String str = send("SHOW_FORUM_USERS \0" + forumID);
		assertTrue(str.startsWith("ANS_SHOW_FORUM_USERS")); // test premissions
		register(forumID);
		loginUser(forumID);
		str = send("SHOW_FORUM_USERS \0" + forumID);
		assertTrue(str.startsWith("ANS_SHOW_FORUM_USERS"));
	}
}
